package com.mzw.huaxiarealestatebackend.service.impl;


import com.mzw.huaxiarealestatebackend.common.utils.DateFormat;
import com.mzw.huaxiarealestatebackend.common.utils.FileUtil;
import com.mzw.huaxiarealestatebackend.common.utils.UIDUtil;
import com.mzw.huaxiarealestatebackend.dao.PanFileDao;
import com.mzw.huaxiarealestatebackend.dao.ProjectDao;
import com.mzw.huaxiarealestatebackend.entity.PanFile;
import com.mzw.huaxiarealestatebackend.entity.Project;
import com.mzw.huaxiarealestatebackend.service.PanService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.core.io.Resource;
import org.springframework.core.io.UrlResource;
import org.springframework.http.HttpHeaders;
import org.springframework.http.MediaType;
import org.springframework.http.ResponseEntity;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.web.multipart.MultipartFile;

import java.io.File;
import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.Paths;
import java.text.SimpleDateFormat;
import java.time.LocalDateTime;
import java.time.ZoneId;
import java.util.Date;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

@Service
public class PanServiceImpl implements PanService {
    @Value("${app.FILE_ROOT}")
    private String FILE_ROOT;

    @Autowired
    private ProjectDao projectMapper;

    @Autowired
    private PanFileDao panFileMapper;

    @Override
    public Map<String, String> createDirectoryStructure(String pjtNo) {
        Project project = projectMapper.selectById(pjtNo);
        String projectName = project.getPjtName();
        Map<String, String> resp = new HashMap<>();
        Map<String, String> fileDemo = new HashMap<>();

        // 获取项目编号
        fileDemo.put("type", "0");
        fileDemo.put("length", "0 B");
        fileDemo.put("lastUpdateTime", DateFormat.getNowDateFormat());
        fileDemo.put("p_id", String.valueOf(pjtNo));

        //新建项目（云盘）
        try {
//            projectMapper.insert(project);
            Path rootPath = Paths.get(FILE_ROOT);

            // 在projectPans根目录下创建子目录
            Path projectDirectoryPath = rootPath.resolve(projectName);
            Files.createDirectories(projectDirectoryPath);
            String projectDirectoryID = UIDUtil.getUUID(8);
            fileDemo.put("fileID", projectDirectoryID);
            fileDemo.put("fileName", projectName);
            fileDemo.put("parentPath", rootPath.toString());
            fileDemo.put("parentID", "0");
            panFileMapper.insertOne(fileDemo);

            // 在项目目录下创建一级文件夹
            String jpgDirectory = "jpg";
            Path jpgDirectoryPath = projectDirectoryPath.resolve(jpgDirectory);
            Files.createDirectories(jpgDirectoryPath);
            String jpgDirectoryID = UIDUtil.getUUID(8);
            fileDemo.replace("fileID", jpgDirectoryID);
            fileDemo.replace("fileName", jpgDirectory);
            fileDemo.replace("parentPath", projectDirectoryPath.toString());
            fileDemo.replace("parentID", projectDirectoryID);
            panFileMapper.insertOne(fileDemo);

            String laterDirectory = "后期文件";
            Path laterDirectoryPath = projectDirectoryPath.resolve(laterDirectory);
            Files.createDirectories(laterDirectoryPath);
            String laterDirectoryID = UIDUtil.getUUID(8);
            fileDemo.replace("fileID", laterDirectoryID);
            fileDemo.replace("fileName", laterDirectory);
            fileDemo.replace("parentPath", projectDirectoryPath.toString());
            fileDemo.replace("parentID", projectDirectoryID);
            panFileMapper.insertOne(fileDemo);

            String modelDirectory = "模型文件";
            Path modelDirectoryPath = projectDirectoryPath.resolve(modelDirectory);
            Files.createDirectories(modelDirectoryPath);
            String modelDirectoryID = UIDUtil.getUUID(8);
            fileDemo.replace("fileID", modelDirectoryID);
            fileDemo.replace("fileName", modelDirectory);
            fileDemo.replace("parentPath", projectDirectoryPath.toString());
            fileDemo.replace("parentID", projectDirectoryID);
            panFileMapper.insertOne(fileDemo);

            String sampleDirectory = "小样";
            Path sampleDirectoryPath = projectDirectoryPath.resolve(sampleDirectory);
            Files.createDirectories(sampleDirectoryPath);
            String sampleDirectoryID = UIDUtil.getUUID(8);
            fileDemo.replace("fileID", sampleDirectoryID);
            fileDemo.replace("fileName", sampleDirectory);
            fileDemo.replace("parentPath", projectDirectoryPath.toString());
            fileDemo.replace("parentID", projectDirectoryID);
            panFileMapper.insertOne(fileDemo);

            String renderDirectory = "渲染文件";
            Path renderDirectoryPath = projectDirectoryPath.resolve(renderDirectory);
            Files.createDirectories(renderDirectoryPath);
            String renderDirectoryID = UIDUtil.getUUID(8);
            fileDemo.replace("fileID", renderDirectoryID);
            fileDemo.replace("fileName", renderDirectory);
            fileDemo.replace("parentPath", projectDirectoryPath.toString());
            fileDemo.replace("parentID", projectDirectoryID);
            panFileMapper.insertOne(fileDemo);

            String resourceDirectory = "资料";
            Path resourceDirectoryPath = projectDirectoryPath.resolve(resourceDirectory);
            Files.createDirectories(resourceDirectoryPath);
            String resourceDirectoryID = UIDUtil.getUUID(8);
            fileDemo.replace("fileID", resourceDirectoryID);
            fileDemo.replace("fileName", resourceDirectory);
            fileDemo.replace("parentPath", projectDirectoryPath.toString());
            fileDemo.replace("parentID", projectDirectoryID);
            panFileMapper.insertOne(fileDemo);

            //在一级文件下创建耳机文件夹
            String originalDirectory = "原始文件";
            Path originalDirectoryPath = laterDirectoryPath.resolve(originalDirectory);
            Files.createDirectories(originalDirectoryPath);
            String originalDirectoryID = UIDUtil.getUUID(8);
            fileDemo.replace("fileID", originalDirectoryID);
            fileDemo.replace("fileName", originalDirectory);
            fileDemo.replace("parentPath", laterDirectoryPath.toString());
            fileDemo.replace("parentID", laterDirectoryID);
            panFileMapper.insertOne(fileDemo);

            String originalModelDirectory = "原始模型";
            String finalModelDirectory = "最终模型";
            Path originalModelDirectoryPath = modelDirectoryPath.resolve(originalModelDirectory);
            Path finalModelDirectoryPath = modelDirectoryPath.resolve(finalModelDirectory);
            Files.createDirectories(originalModelDirectoryPath);
            Files.createDirectories(finalModelDirectoryPath);
            fileDemo.replace("fileID", UIDUtil.getUUID(8));
            fileDemo.replace("fileName", originalModelDirectory);
            fileDemo.replace("parentPath", modelDirectoryPath.toString());
            fileDemo.replace("parentID", modelDirectoryID);
            panFileMapper.insertOne(fileDemo);
            fileDemo.replace("fileID", UIDUtil.getUUID(8));
            fileDemo.replace("fileName", finalModelDirectory);
            fileDemo.replace("parentPath", modelDirectoryPath.toString());
            panFileMapper.insertOne(fileDemo);

            String originalRenderDirectory = "原始渲染";
            String finalRenderDirectory = "最终渲染";
            Path originalRenderDirectoryPath = renderDirectoryPath.resolve(originalRenderDirectory);
            Path finalRenderDirectoryPath = renderDirectoryPath.resolve(finalRenderDirectory);
            Files.createDirectories(originalRenderDirectoryPath);
            Files.createDirectories(finalRenderDirectoryPath);
            fileDemo.replace("fileID", UIDUtil.getUUID(8));
            fileDemo.replace("fileName", originalRenderDirectory);
            fileDemo.replace("parentPath", renderDirectoryPath.toString());
            fileDemo.replace("parentID", renderDirectoryID);
            panFileMapper.insertOne(fileDemo);
            fileDemo.replace("fileID", UIDUtil.getUUID(8));
            fileDemo.replace("fileName", finalRenderDirectory);
            fileDemo.replace("parentPath", renderDirectoryPath.toString());
            panFileMapper.insertOne(fileDemo);
        } catch (Exception exception) {
            resp.put("information", "error");
        }

        resp.put("information", "success");
        return resp;
    }

    @Override
    public List<PanFile> getFile(Map<String, String> map) {
        String parentPath = map.get("parentPath");
        System.out.println(parentPath);
        List<PanFile> allFile = panFileMapper.getAllFile(parentPath);
        return allFile;
    }

    @Override
    public ResponseEntity<String> uploadFile(List<MultipartFile> files, Map<String, String> map) {
        Map<String, String> panFile = new HashMap<>();

        try {
            String parentPath = map.get("parentPath");
            String parentId = map.get("parentID");

            LocalDateTime currentDateTime = LocalDateTime.now();

            String temp;

            List<PanFile> panFiles = panFileMapper.getAllFile(parentPath);

            for (MultipartFile file : files) {
                //检查是否有重名文件，若存在，则删除前一个文件
                for(PanFile item : panFiles) {
                    if(file.getOriginalFilename().equals(item.getFileName())) {
                        temp = parentId;
                        while(!temp.equals("0")) {
                            Map<String, String> update = new HashMap<>();
                            update.put("parentID", temp);
                            update.put("time", String.valueOf(currentDateTime));
                            String oldSizeS = panFileMapper.getLength(temp);
                            long oldSize =  FileUtil.parseFileSize(oldSizeS);
                            String newSize = FileUtil.formatFileSize(oldSize - FileUtil.parseFileSize(item.getLength()));
                            update.put("size", newSize);
                            panFileMapper.updateTimeAndSize(update);
                            temp = panFileMapper.getParentId(temp);
                        }
                        panFileMapper.deleteFile(item.getFileID());
                    }
                }

                //在云盘新建文件
                String fileName = file.getOriginalFilename();
                File destinationFile = new File(parentPath + "\\" + fileName);
                file.transferTo(destinationFile);

                //在数据库新建记录
                panFile.put("fileID", UIDUtil.getUUID(8));
                panFile.put("p_id", String.valueOf(panFileMapper.getpID(parentId)));
                panFile.put("fileName", fileName);
                panFile.put("parentID", parentId);
                panFile.put("parentPath", parentPath);
                long size = file.getSize();
                panFile.put("length", FileUtil.formatFileSize(size));
                panFile.put("type", "1");

                panFile.put("lastUpdateTime", String.valueOf(currentDateTime));
                panFileMapper.insertOne(panFile);

                //更新父目录文件大小和修改时间
                temp = parentId;
                while(!temp.equals("0")) {
                    Map<String, String> update = new HashMap<>();
                    update.put("parentID", temp);
                    update.put("time", String.valueOf(currentDateTime));
                    String oldSizeS = panFileMapper.getLength(temp);
                    long oldSize =  FileUtil.parseFileSize(oldSizeS);
                    String newSize = FileUtil.formatFileSize(oldSize + size);
                    update.put("size", newSize);
                    panFileMapper.updateTimeAndSize(update);
                    temp = panFileMapper.getParentId(temp);
                }
            }

            return ResponseEntity.ok("File uploaded successfully");
        } catch (Exception e) {
            e.printStackTrace();
            return ResponseEntity.status(500).body("File upload failed");
        }
    }

    @Override
    public Boolean couldUpload(Map<String, String> map) {
        String parentPath = map.get("parentPath");
        List<PanFile> allFile = panFileMapper.getAllFile(parentPath);

        for(PanFile panFile : allFile) {
            if(panFile.getType() == 0) {
                return false;
            }
        }
        return true;
    }

    @Override
    public ResponseEntity<byte[]> downloadFile(Map<String, String> map)  {
        String fileName = map.get("fileName");
        String parentPath = map.get("parentPath");
        Path filePath = Path.of(parentPath, fileName);

        try {
            Resource resource = new UrlResource(filePath.toUri());
            // 检查文件是否存在并可读
            if (resource.exists() && resource.isReadable()) {
                HttpHeaders headers = new HttpHeaders();
                headers.add(HttpHeaders.CONTENT_DISPOSITION, "attachment; filename=" + fileName);
                headers.add(HttpHeaders.CONTENT_TYPE, MediaType.APPLICATION_OCTET_STREAM_VALUE + "; charset=UTF-8");

                // 读取文件内容并返回字节数组
                byte[] fileContent = resource.getInputStream().readAllBytes();

                // 返回ResponseEntity，其中包含文件的字节数组
                return ResponseEntity.ok()
                        .headers(headers)
                        .body(fileContent);
            }
        } catch (Exception e) {
            e.printStackTrace();
        }
        // 如果文件不存在，返回404状态码
        return ResponseEntity.notFound().build();
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public Map<String, String> deleteFile(Map<String, String> map) {
        Map<String, String> res = new HashMap<>();
        String fileId = map.get("fileId");
        String fileName = map.get("fileName");
        String parentId = map.get("parentId");
        String parentPath = map.get("parentPath");
        String length = map.get("length");

        try {
            //删除数据库信息
            panFileMapper.deleteFile(fileId);

            //删除云盘中的文件
            String filePath = parentPath + "\\" + fileName;
            Path path = Paths.get(filePath);
            Files.delete(path);

            //更新所有父文件大小和修改时间
            LocalDateTime currentDateTime = LocalDateTime.now();
            while(!parentId.equals("0")) {
                Map<String, String> delete = new HashMap<>();
                delete.put("parentID", parentId);
                delete.put("time", String.valueOf(currentDateTime));
                String oldSizeS = panFileMapper.getLength(parentId);
                long oldSize =  FileUtil.parseFileSize(oldSizeS);
                long size = FileUtil.parseFileSize(length);
                String newSize = FileUtil.formatFileSize(oldSize - size);
                delete.put("size", newSize);
                panFileMapper.updateTimeAndSize(delete);
                parentId = panFileMapper.getParentId(parentId);
            }

        } catch (Exception e) {
            System.out.println(e);
            res.put("errorMessage", "error");
            return res;
        }

        res.put("errorMessage", "success");
        return res;
    }

}
